package com.songyang.yougnsql.core.table;

import com.songyang.yougnsql.common.ErrorMsg;
import com.songyang.yougnsql.common.ExceptionHandler;
import com.songyang.yougnsql.common.YoungSQLException;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;

/**
 * @ClassName BootStrap
 * @Description 记录第一个表的uid
 * @date 2022/12/29 10:20
 * @Author yanceysong
 * @Version 1.0
 */
public class BootStrap {
    public static final String BOOTSTRAP_FILE = "YoungSQL.bs";
    public static final String BOOTSTRAP_TMP_SUFFIX = "YoungSQL.bs_tmp";

    String path;
    File file;

    private BootStrap(String path, File file) {
        this.path = path;
        this.file = file;
    }

    /**
     * 创建
     *
     * @param path 所在的路径
     * @return 返回值
     */
    public static BootStrap create(String path) {
        removeBadTmp(path);
        File f = new File(path + File.separator + BOOTSTRAP_FILE);
        try {
            //如果不存在就去创建，创建失败就抛异常
            if (!f.exists() && !f.createNewFile()) {
                throw new YoungSQLException(ErrorMsg.FILE_CREATE_FAILED_EXCEPTION);
            }
            if (!f.canRead() || !f.canWrite()) {
                throw new YoungSQLException(ErrorMsg.FILE_CANNOT_RW_EXCEPTION);
            }
        } catch (YoungSQLException | IOException e) {
            ExceptionHandler.handler(e);
        }

        return new BootStrap(path, f);
    }

    /**
     * 打开一个文件并且加载
     *
     * @param path 路径
     * @return 结果
     */
    public static BootStrap open(String path) {
        removeBadTmp(path);
        File f = new File(path + File.separator + BOOTSTRAP_FILE);
        try {
            if (!f.exists()) {
                throw new YoungSQLException(ErrorMsg.FILE_CREATE_FAILED_EXCEPTION);
            }
            if (!f.canRead() || !f.canWrite()) {
                throw new YoungSQLException(ErrorMsg.FILE_CANNOT_RW_EXCEPTION);
            }
        } catch (YoungSQLException e) {
            ExceptionHandler.handler(e);
        }
        return new BootStrap(path, f);
    }

    /**
     * 删除坏掉的临时文件
     *
     * @param path 原路径
     */
    private static void removeBadTmp(String path) {
        new File(path + File.separator + BOOTSTRAP_TMP_SUFFIX).delete();
    }

    /**
     * 获取第一个表的uid
     *
     * @return uid数据
     */
    public byte[] load() {
        byte[] buf = null;
        try {
            buf = Files.readAllBytes(file.toPath());
        } catch (IOException e) {
            ExceptionHandler.handler(e);
        }
        return buf;
    }

    /**
     * 更新第一个标的uid数据
     *
     * @param data uid数据
     */
    public void update(byte[] data) {
        File tmp = new File(path + File.separator + BOOTSTRAP_TMP_SUFFIX);
        try {
            tmp.createNewFile();
            if (!tmp.canRead() || !tmp.canWrite()) {
                throw new YoungSQLException(ErrorMsg.FILE_CANNOT_RW_EXCEPTION);
            }
        } catch (Exception e) {
            ExceptionHandler.handler(e);
        }

        try (FileOutputStream out = new FileOutputStream(tmp)) {
            out.write(data);
            out.flush();
           Files.copy(tmp.toPath(), new File(path + File.separator + BOOTSTRAP_FILE).toPath(), StandardCopyOption.REPLACE_EXISTING);
            tmp.delete();
//            Files.move(tmp.toPath(), new File(path + File.separator+BOOTSTRAP_FILE).toPath(), StandardCopyOption.REPLACE_EXISTING);
            file = new File(path + File.separator + BOOTSTRAP_FILE);
            if (!file.canRead() || !file.canWrite()) {
                throw new YoungSQLException(ErrorMsg.FILE_CANNOT_RW_EXCEPTION);
            }
        } catch (IOException | YoungSQLException e) {
            ExceptionHandler.handler(e);
        }
    }
}
